#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2022/10/19 15:11
# file: user.py
# author: lotus163
from typing import Optional

from fastapi import APIRouter, Depends

from ...core.custom_exc import CommonException
from ...core.datascope import DataScope
from ...core.deps import UserDepends, get_user_depends
from ...core.result import Result, result_success, ResultData, ResultList, ResultDeptTree
from ...crud import RoleDao, UserDao
from ...models import SysUserRoleDb
from ...schemas import SysRoleSch, SysUserSch
from ...schemas.system.role import ChangeRoleStatusForm, CancelUserRoleForm, \
    CancelAllUserRoleForm, SysRoleAdd
from ...service.system.dept import DeptService
from ...service.system.role_dept import RoleDeptService
from ...service.system.role_menu import RoleMenuService
from ...service.system.user import UserService
from ...service.system.user_role import UserRoleService
from ...utils.form_util import get_form_dict
from ...utils.string_util import get_array_by_str

router = APIRouter(prefix="/role", tags=["角色"])


@router.put("", response_model=Result, summary='修改角色')
async def update_role(form: SysRoleSch, user_depends: UserDepends = Depends(get_user_depends)):
    # 添加创建者
    form.updateBy = user_depends.login_user.user.userName
    role_db = await RoleDao.get_db_or_none(roleId=form.roleId)
    await RoleDao.update_sch(obj=role_db, **form.dict(exclude_none=True))
    await RoleMenuService().update_menus_by_role_id(form.roleId, form.menuIds)
    return result_success()


@router.post("", response_model=Result, summary='新增角色')
async def add_role(form: SysRoleAdd, user_depends: UserDepends = Depends(get_user_depends)):
    # 添加创建者
    form.createBy = user_depends.login_user.user.userName
    # 成功则增加了用户，失败，则抛出异常
    role_sch = await RoleDao.add_sch(**form.dict(exclude_none=True))
    await RoleMenuService().add_menus_by_role_id(role_sch.roleId, form.menuIds)
    return result_success()


@router.get("/authUser/allocatedList", response_model=ResultList[SysUserSch], summary='根据角色查询用户列表')
async def get_allocated_list(pageNum: int, pageSize: int,
                             roleId: Optional[int],
                             userName: Optional[str] = None,
                             phonenumber: Optional[str] = None,
                             user_depends: UserDepends = Depends(get_user_depends)):
    # 准备查询的参数
    form_dict = {}
    if userName:
        form_dict["userName"] = userName
    if phonenumber:
        form_dict["phonenumber"] = phonenumber
    form_dict["userId__in"] = await UserRoleService().get_user_ids_by_role_id(roleId)
    # 查询
    users_sch = await UserDao.get_list_sch_page(pageSize=pageSize, pageNum=pageNum, **form_dict)
    total = await UserDao.get_list_count(**form_dict)
    return result_success(msg="查询成功", rows=users_sch, total=total)


@router.put("/authUser/cancel", response_model=Result, summary='取消授权用户')
async def cancel_auth_user(form: CancelUserRoleForm, user_depends: UserDepends = Depends(get_user_depends)):
    await UserRoleService().cancel_role_by_user_id(form.userId, form.roleId)
    return result_success()


@router.put("/authUser/cancelAll", response_model=Result, summary='批量取消授权用户')
async def cancel_auth_all(form: CancelAllUserRoleForm, user_depends: UserDepends = Depends(get_user_depends)):
    await UserRoleService().cancel_role_by_user_ids(form.userIds, form.roleId)
    return result_success()


@router.put("/authUser/selectAll", response_model=Result, summary='批量选择用户授权')
async def select_auth_user_all(roleId:int,userIds:str,
                               user_depends: UserDepends = Depends(get_user_depends)):
    user_ids = get_array_by_str(userIds)
    await UserRoleService().add_role_by_user_ids(user_ids, roleId)
    return result_success()


@router.get("/authUser/unallocatedList", response_model=ResultList[SysUserSch], summary='查询未分配用户的角色列表')
async def get_unallocated_list(pageNum: int, pageSize: int,
                               roleId: Optional[int],
                               userName: Optional[str] = None,
                               phonenumber: Optional[str] = None,
                               user_depends: UserDepends = Depends(get_user_depends)):
    # 准备查询的参数
    form_dict = {}
    if userName:
        form_dict["userName"] = userName
    if phonenumber:
        form_dict["phonenumber"] = phonenumber
    allocated_user_ids = await UserRoleService().get_user_ids_by_role_id(roleId)
    all_user_ids = await UserService().get_all_user_ids()
    unallocated_user_ids_set = set(all_user_ids).difference(set(allocated_user_ids))
    form_dict["userId__in"] = list(unallocated_user_ids_set)
    # 查询
    users_sch = await UserDao.get_list_sch_page(pageSize=pageSize, pageNum=pageNum, **form_dict)
    total = await UserDao.get_list_count(**form_dict)
    return result_success(msg="查询成功", rows=users_sch, total=total)


@router.put("/changeStatus", response_model=Result, summary='状态修改')
async def change_status(form: ChangeRoleStatusForm, user_depends: UserDepends = Depends(get_user_depends)):
    role_db = await RoleDao.get_db_or_none(roleId=form.roleId)
    await RoleDao.update_sch(obj=role_db, **form.dict(exclude_none=True))
    return result_success()


@router.put("/dataScope", response_model=Result, summary='修改保存数据权限')
async def data_scope(form: SysRoleSch, user_depends: UserDepends = Depends(get_user_depends)):
    role_db = await RoleDao.get_db_or_none(roleId=form.roleId)
    form.updateBy = user_depends.login_user.user.userName
    await RoleDao.update_sch(role_db, **form.dict(exclude_none=True))
    await RoleDeptService().update_depts_by_role_id(form.roleId, form.deptIds)
    return result_success()


@router.get("/deptTree/{roleId}", response_model=ResultDeptTree, summary='获取对应角色部门树列表')
async def dept_tree(roleId: int, user_depends: UserDepends = Depends(get_user_depends)):
    dept_ids = await RoleDeptService().get_dept_ids_by_role_id(roleId)
    dept_tree = await DeptService().get_dept_tree()
    return result_success(depts=dept_tree, checkedKeys=dept_ids)


@router.post("/export", response_model=Result, summary='导出角色')
async def export_roles():
    pass


@router.get("/list", response_model=ResultList[SysRoleSch], summary='获取所有角色')
async def get_roles_list(pageNum: int, pageSize: int,
                         roleName: Optional[str] = None,
                         roleKey: Optional[str] = None,
                         status: Optional[str] = None,
                         user_depends: UserDepends = Depends(get_user_depends)):
    # 时间
    start, end = user_depends.request_service.get_params_time()
    # 准备查询的参数
    form_dict = get_form_dict(form=SysRoleAdd(roleName=roleName, roleKey=roleKey, status=status),
                              start=start, end=end, time_range="createTime__range")
    # 查询
    roles_sch = await RoleDao.get_list_sch_page(pageSize=pageSize, pageNum=pageNum, **form_dict)
    total = await RoleDao.get_list_count(**form_dict)
    return result_success(msg="查询成功", rows=roles_sch, total=total)


@router.get("/optionselect", response_model=Result, summary='获取角色选择框列表')
async def option_select():
    pass


@router.delete("/{roleIds}", response_model=Result, summary='根据ids删除角色')
async def remove_roles(roleIds: str, user_depends: UserDepends = Depends(get_user_depends)):
    role_ids = get_array_by_str(roleIds)
    for role_id in role_ids:
        if await SysUserRoleDb.exists(roleId=role_id):
            raise CommonException("角色未解除分配，请先修改用户.")
        else:
            await RoleDao.delete_db(roleId=role_id)
            await RoleDeptService().delete_depts_by_role_id(role_id)
            await RoleMenuService().delete_menus_by_role_id(role_id)
    return result_success()


@router.get("/{roleId}", response_model=ResultData, summary='根据角色编号获取详细信息')
async def get_role_info(roleId: int, user_depends: UserDepends = Depends(get_user_depends)):
    role_sch = await RoleDao.get_sch_or_none(roleId=roleId)
    return result_success(data=role_sch)
